package model

import (
	"gin/common"
	Mysql "gin/database"
	nlpWord "gin/tai/dict/word"
	"github.com/Gre-Z/common/jtime"
	"github.com/spf13/viper"
	nlp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/nlp/v20190408"
	"gorm.io/gorm"
	"strings"
)

type DictWord struct {
	Id           uint64           `json:"id" gorm:"column:id;primaryKey;type:int;autoIncrement"`
	DictId       uint64           `json:"dict_id" gorm:"column:dict_id"`
	Word         string           `json:"word" gorm:"column:word"`
	Pos          string           `json:"pos" gorm:"column:pos"`
	Created      jtime.TstampTime `json:"created" gorm:"column:created;autoCreateTime"`
	Updated      jtime.TstampTime `json:"updated" gorm:"column:updated;autoUpdateTime"`
	DontNeedSync bool             `gorm:"-"`
	WordSpeech   WordSpeech       `json:"word_speech" gorm:"foreignKey:code;references:pos"`
	ExtendCode   string           `json:"extend_code" gorm:"column:extend_code"`
}

// 设置表名
func (DictWord) TableName() string {
	return "dict_word"
}

func (this *DictWord) Insert() (id uint64, err error) {
	db := Mysql.DB
	result := db.Create(&this)

	if result.Error != nil {
		err = result.Error
		return
	}
	return
}

func (this *DictWord) Find(Param common.Filter) (resData DictWord, err error) {

	dictOne := new(DictWord)
	db := Mysql.DB

	// 组装过滤条件
	if Param.Filter != nil {
		for key, val := range Param.Filter {
			vals := val.(map[string]interface{})
			if strings.Contains(key, "bw_") {
				db = db.Where(vals["condition"], vals["val1"], vals["val2"])
			} else {
				db = db.Where(vals["condition"], vals["val"])
			}
		}
	} else {
		db = db.Where("?", "1=1")
	}

	// 应用分页
	//db = db.Select(Param.Fields)

	result := db.Preload("WordSpeech").Last(&dictOne)
	if result.Error != nil {
		err = result.Error
	}

	return *dictOne, err
}

func (this *DictWord) Select(Param *common.SelectQueryParam) (total int64, resData []DictWord, err error) {

	dictWords := make([]DictWord, 0)
	db := Mysql.DB

	// 组装过滤条件
	if Param.Filter.Filter != nil {
		for key, val := range Param.Filter.Filter {
			vals := val.(map[string]interface{})
			if strings.Contains(key, "bw_") {
				db = db.Where(vals["condition"], vals["val1"], vals["val2"])
			} else {
				db = db.Where(vals["condition"], vals["val"])
			}
		}
	} else {
		db = db.Where("?", "1=1")
	}

	// 获取总条数
	db.Model(&DictWord{}).Count(&total)

	// 查找所有数据

	// 应用分页
	db = db.Select(Param.Fields).Limit(Param.Limit).Offset(Param.Offset)

	// 应用排序参数
	if Param.Order != "" {
		db = db.Order(Param.Order)
	}

	result := db.Preload("WordSpeech").Find(&dictWords)
	if result.Error != nil {
		err = result.Error
		return
	}

	return total, dictWords, err
}

func (this *DictWord) FindById(id uint64) (resData DictWord, err error) {

	dictOne := new(DictWord)
	db := Mysql.DB

	db = db.Where("id = ?", id)

	// 应用分页
	db = db.Select("*")

	result := db.First(&dictOne)
	if result.Error != nil {
		err = result.Error
		return *dictOne, err
	}

	return *dictOne, err
}

// 更新dict
func (this *DictWord) Update(dict DictWord) (DictWord, error) {
	db := Mysql.DB
	result := db.Updates(&dict)
	if result.Error != nil {
		return dict, result.Error
	}

	return this.FindById(dict.Id)
}

func (this *DictWord) Delete(dict DictWord) {
	Mysql.DB.Delete(&dict)
}

// 批量删除
func (this *DictWord) DeleteByFilter(param *common.Filter) error {
	paramQuery := common.SelectQueryParam{
		Filter: *param,
		Limit:  viper.GetInt("mysql.maxQueryNumber"),
		Offset: 0,
		Fields: "*",
	}
	total, rows, err := this.Select(&paramQuery)

	if err != nil || total <= 0 {
		return err
	}
	db := Mysql.DB
	for _, row := range rows {
		res := db.Delete(&row)
		if res.Error != nil {
			return res.Error
		}
	}
	return err
}

// 在词条被删除后
func (this *DictWord) AfterDelete(tx *gorm.DB) (err error) {

	if this.DictId > 0 {
		var dict Dict

		err = FindById(&dict, this.DictId, nil)

		if err != nil {
			return err
		}
		if dict.DictId != "" {
			wordItems := []*nlp.WordItem{
				{
					Text:       &this.Word,
					CreateTime: nil,
					Pos:        &this.Pos,
				},
			}

			_, err = nlpWord.Delete(dict.DictId, &wordItems)
			if err != nil {
				return err
			}
		}
	}
	return err
}

// 在词条创建后
func (this *DictWord) AfterCreate(tx *gorm.DB) (err error) {
	if this.DontNeedSync {
		return
	}
	if this.DictId > 0 {
		var dict Dict
		err = FindById(&dict, this.DictId, nil)
		if err != nil {
			return err
		}
		if dict.DictId != "" {
			wordItems := []*nlp.WordItem{
				{
					Text: &this.Word,
					Pos:  &this.Pos,
				},
			}

			_, err = nlpWord.Create(dict.DictId, &wordItems)
			if err != nil {
				return err
			}
		}
	}
	return err
}
